"""
机器信息相关路由模块

该模块提供服务器机器信息相关的API端点，包括获取所有机器列表和单个机器详情。
所有端点都需要通过JWT令牌进行身份验证，确保只有授权用户可以访问系统资源信息。
支持分页和过滤功能。
"""

from fastapi import APIRouter, Depends, Query, HTTPException, status
from typing import List, Optional
from app.schemas.machine import Machine
from app.schemas.user import TokenData
from app.schemas.response import ApiResponse
from app.core.security import verify_token
from app.services.machine_service import MachineService
from app.core.deps import get_db
from sqlalchemy.orm import Session
from pydantic import BaseModel

# 定义创建机器的请求模型
class MachineCreate(BaseModel):
    name: str
    ip: str
    os: str = ""
    purpose: str = ""
    owner: str = ""
    location: str = ""
    port: int = 22

# 定义更新机器的请求模型
class MachineUpdate(BaseModel):
    name: Optional[str] = None
    ip: Optional[str] = None
    monitor_config: Optional[str] = None
    os: Optional[str] = None
    purpose: Optional[str] = None
    owner: Optional[str] = None
    location: Optional[str] = None
    status: Optional[str] = None

router = APIRouter()

@router.post("/", response_model=ApiResponse)
async def create_machine(
    machine_data: MachineCreate,
    token_data: TokenData = Depends(verify_token),
    db: Session = Depends(get_db)
):
    """创建新机器
    
    Args:
        machine_data (MachineCreate): 机器创建信息
        token_data (TokenData): 从JWT令牌中解析的用户信息，通过依赖注入提供
        db (Session): 数据库会话对象，通过依赖注入提供
        
    Returns:
        ApiResponse: 包含创建的机器信息
    """
    machine_service = MachineService(db)
    # 检查IP是否已存在
    existing_machine = machine_service.get_machine_by_ip(machine_data.ip)
    if existing_machine:
        return ApiResponse(
            success=False,
            message="该IP地址的机器已存在"
        )
    
    # 准备机器数据
    machine_dict = {
        "name": machine_data.name,
        "ip": machine_data.ip,
        "os": machine_data.os,
        "purpose": machine_data.purpose,
        "owner": machine_data.owner,
        "location": machine_data.location,
        "status": "offline",  # 新机器默认状态为离线
        "cpu": 0,
        "memory": 0,
        "disk": 0
    }
    
    # 创建机器
    created_machine = machine_service.create_machine(machine_dict)
    return ApiResponse(
        success=True,
        data=created_machine,
        message="机器创建成功"
    )

@router.get("/", response_model=ApiResponse)
async def get_machines(
    token_data: TokenData = Depends(verify_token),
    db: Session = Depends(get_db),
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回的记录数限制"),
    status: Optional[str] = Query(None, description="按状态过滤 (online/offline/warning)"),
    ip: Optional[str] = Query(None, description="按IP地址过滤")
):
    """获取所有机器信息端点
    
    返回系统中所有服务器机器的列表信息，包括机器名称、IP地址、状态等基本信息。
    支持分页、状态过滤和IP地址过滤。
    
    Args:
        token_data (TokenData): 从JWT令牌中解析的用户信息，通过依赖注入提供
        db (Session): 数据库会话对象，通过依赖注入提供
        skip (int): 跳过的记录数，默认为0
        limit (int): 返回的记录数限制，默认为100，最大1000
        status (Optional[str]): 按状态过滤机器
        ip (Optional[str]): 按IP地址过滤机器
        
    Returns:
        ApiResponse: 包含机器信息列表的响应
    """
    machine_service = MachineService(db)
    if ip:
        # 根据IP地址查找机器
        machine = machine_service.get_machine_by_ip(ip)
        machines = [machine] if machine else []
    else:
        machines = machine_service.get_all_machines(skip=skip, limit=limit, status=status)
    return ApiResponse(
        success=True,
        data=machines
    )

@router.get("/{machine_id}", response_model=ApiResponse)
async def get_machine_detail(
    machine_id: int,
    token_data: TokenData = Depends(verify_token),
    db: Session = Depends(get_db)
):
    """获取单个机器详情端点
    
    根据机器ID获取特定服务器机器的详细信息，包括CPU、内存、磁盘使用率等监控数据。
    
    Args:
        machine_id (int): 机器ID
        token_data (TokenData): 从JWT令牌中解析的用户信息，通过依赖注入提供
        db (Session): 数据库会话对象，通过依赖注入提供
        
    Returns:
        ApiResponse: 包含指定机器详细信息的响应
    """
    machine_service = MachineService(db)
    machine = machine_service.get_machine_detail(machine_id)
    return ApiResponse(
        success=True,
        data=machine
    )

@router.put("/{machine_id}", response_model=ApiResponse)
async def update_machine(
    machine_id: int,
    machine_data: MachineUpdate,
    token_data: TokenData = Depends(verify_token),
    db: Session = Depends(get_db)
):
    """更新机器信息端点
    
    更新指定机器的信息，包括监控配置等。
    
    Args:
        machine_id (int): 机器ID
        machine_data (MachineUpdate): 机器更新信息
        token_data (TokenData): 从JWT令牌中解析的用户信息，通过依赖注入提供
        db (Session): 数据库会话对象，通过依赖注入提供
        
    Returns:
        ApiResponse: 包含更新后机器信息的响应
    """
    machine_service = MachineService(db)
    
    # 过滤掉None值，只更新提供的字段
    update_data = {k: v for k, v in machine_data.dict().items() if v is not None}
    
    # 如果提供了IP地址，检查是否已存在
    if "ip" in update_data:
        existing_machine = machine_service.get_machine_by_ip(update_data["ip"])
        if existing_machine and existing_machine["id"] != machine_id:
            return ApiResponse(
                success=False,
                message="该IP地址的机器已存在"
            )
    
    machine = machine_service.update_machine(machine_id, update_data)
    return ApiResponse(
        success=True,
        data=machine,
        message="机器信息更新成功"
    )

@router.delete("/{machine_id}", response_model=ApiResponse)
async def delete_machine(
    machine_id: int,
    token_data: TokenData = Depends(verify_token),
    db: Session = Depends(get_db)
):
    """删除机器端点
    
    软删除指定的机器记录。
    
    Args:
        machine_id (int): 机器ID
        token_data (TokenData): 从JWT令牌中解析的用户信息，通过依赖注入提供
        db (Session): 数据库会话对象，通过依赖注入提供
        
    Returns:
        ApiResponse: 删除结果响应
    """
    machine_service = MachineService(db)
    machine_service.delete_machine(machine_id)
    return ApiResponse(
        success=True,
        message="机器删除成功"
    )

@router.put("/{machine_id}/activate", response_model=ApiResponse)
async def update_machine_activate(
    machine_id: int,
    is_activate: bool,
    token_data: TokenData = Depends(verify_token),
    db: Session = Depends(get_db)
):
    """更新机器激活状态端点
    
    更新指定机器的激活状态。
    
    Args:
        machine_id (int): 机器ID
        is_activate (bool): 激活状态
        token_data (TokenData): 从JWT令牌中解析的用户信息，通过依赖注入提供
        db (Session): 数据库会话对象，通过依赖注入提供
        
    Returns:
        ApiResponse: 更新结果响应
    """
    machine_service = MachineService(db)
    
    # 准备更新数据
    update_data = {"is_activate": is_activate}
    
    machine = machine_service.update_machine(machine_id, update_data)
    if machine:
        return ApiResponse(
            success=True,
            message=f"机器监控已{'启用' if is_activate else '禁用'}"
        )
    else:
        return ApiResponse(
            success=False,
            message="机器不存在"
        )
